package com.plugin.manage.controller;

import com.plugin.core.bean.LogAop;
import com.plugin.core.model.entity.SysMenu;
import com.plugin.manage.common.PageResult;
import com.plugin.manage.common.RespObj;
import com.plugin.manage.service.ISysMenuService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

/**
 * 系统菜单控制器
 * 
 * @author mark
 * @date 2025-07-28
 */
@RestController
@RequestMapping("/sys/menu")
@Tag(name = "系统菜单管理", description = "系统菜单管理相关接口")
@Slf4j
public class SysMenuController {

    @Autowired
    private ISysMenuService sysMenuService;

    /**
     * 新增菜单
     * @param sysMenu 菜单信息
     * @return
     */
    @PostMapping("/add")
    @ResponseBody
    @LogAop
    @Operation(summary = "新增菜单", description = "新增系统菜单")
    @PreAuthorize("hasPermission('admin')")
    public RespObj<?> add(@RequestBody SysMenu sysMenu) {
        try {
            Long menuId = sysMenuService.addMenu(sysMenu);
            return new RespObj<>().success(menuId);

        } catch (Exception e) {
            return new RespObj<>().error("新增菜单失败：" + e.getMessage());
        }
    }

    /**
     * 修改菜单
     * @param sysMenu 菜单信息
     * @return
     */
    @PostMapping("/update")
    @ResponseBody
    @LogAop(remark = "修改菜单")
    @Operation(summary = "修改菜单", description = "修改系统菜单")
    @PreAuthorize("hasPermission('admin')")
    public RespObj<?> update(@RequestBody SysMenu sysMenu) {
        try {
            boolean success = sysMenuService.updateMenu(sysMenu);
            if (success) {
                return new RespObj<>().success("修改菜单成功");
            } else {
                return new RespObj<>().error("修改菜单失败");
            }

        } catch (Exception e) {
            return new RespObj<>().error("修改菜单失败：" + e.getMessage());
        }
    }

    /**
     * 菜单列表
     * @param pageIndex 页码
     * @param pageSize 页大小
     * @param menuName 菜单名称
     * @param status 状态
     * @param menuType 菜单类型
     * @param system 系统类型
     * @return
     */
    @PreAuthorize("hasPermission('admin')")
    @LogAop
    @GetMapping("/list")
    @ResponseBody
    @Operation(summary = "菜单列表", description = "分页查询菜单列表")
    public RespObj<?> list(@RequestParam(defaultValue = "1") int pageIndex,
                           @RequestParam(defaultValue = "10") int pageSize,
                           @RequestParam(required = false) String menuName,
                           @RequestParam(required = false) String status,
                           @RequestParam(required = false) String menuType,
                           @RequestParam(required = false) Integer system) {
        try {
            // 构建查询条件
            SysMenu queryMenu = new SysMenu();
            if (org.springframework.util.StringUtils.hasText(menuName)) {
                queryMenu.setMenuName(menuName);
            }
            if (org.springframework.util.StringUtils.hasText(status)) {
                queryMenu.setStatus(status);
            }
            if (org.springframework.util.StringUtils.hasText(menuType)) {
                queryMenu.setMenuType(menuType);
            }
            if (system != null) {
                queryMenu.setSystem(system);
            }

            // 计算偏移量
            int offset = (pageIndex - 1) * pageSize;

            // 查询菜单列表
            List<SysMenu> menuList = sysMenuService.getMenuList(offset, pageSize, queryMenu);

            // 查询总数
            Integer count = sysMenuService.countMenus(queryMenu);

            // 构建分页结果
            return new RespObj<>().success(new PageResult<>(menuList, count));

        } catch (Exception e) {
            return new RespObj<>().error("查询菜单列表失败：" + e.getMessage());
        }
    }

    /**
     * 删除菜单
     * @param menuIds 菜单ID，多个用逗号分隔
     * @return
     */
    @PostMapping("/delete")
    @ResponseBody
    @LogAop(remark = "删除菜单")
    @Operation(summary = "删除菜单", description = "删除系统菜单")
    public RespObj<?> delete(@RequestParam String menuIds) {
        try {
            if (!org.springframework.util.StringUtils.hasText(menuIds)) {
                return new RespObj<>().error("菜单ID不能为空");
            }

            String[] idArray = menuIds.split(",");
            int successCount = 0;
            for (String idStr : idArray) {
                try {
                    Long menuId = Long.valueOf(idStr.trim());
                    if (sysMenuService.deleteMenu(menuId)) {
                        successCount++;
                    }
                } catch (Exception e) {
                    log.error("删除菜单失败，菜单ID：{}", idStr, e);
                }
            }

            return new RespObj<>().success("成功删除" + successCount + "个菜单");

        } catch (Exception e) {
            return new RespObj<>().error("删除菜单失败：" + e.getMessage());
        }
    }

    /**
     * 获取菜单详情
     * @param menuId 菜单ID
     * @return
     */
    @GetMapping("/detail")
    @ResponseBody
    @Operation(summary = "菜单详情", description = "获取菜单详细信息")
    public RespObj<?> detail(@RequestParam Long menuId) {
        try {
            if (menuId == null) {
                return new RespObj<>().error("菜单ID不能为空");
            }

            SysMenu menu = sysMenuService.getMenuById(menuId);
            return new RespObj<>().success(menu);

        } catch (Exception e) {
            return new RespObj<>().error("获取菜单详情失败：" + e.getMessage());
        }
    }

    /**
     * 获取所有菜单
     * @return
     */
    @GetMapping("/all")
    @ResponseBody
    @Operation(summary = "所有菜单", description = "获取所有菜单列表")
    public RespObj<?> all() {
        try {
            List<SysMenu> menus = sysMenuService.getAllMenus();
            return new RespObj<>().success(menus);

        } catch (Exception e) {
            return new RespObj<>().error("查询所有菜单失败：" + e.getMessage());
        }
    }

    /**
     * 构建菜单树
     * @param parentId 父菜单ID
     * @return
     */
    @GetMapping("/tree")
    @ResponseBody
    @Operation(summary = "菜单树", description = "构建菜单树结构")
    public RespObj<?> tree(@RequestParam(defaultValue = "0") Long parentId) {
        try {
            List<SysMenu> menuTree = sysMenuService.buildMenuTree(parentId);
            return new RespObj<>().success(menuTree);

        } catch (Exception e) {
            return new RespObj<>().error("构建菜单树失败：" + e.getMessage());
        }
    }

    /**
     * 根据父菜单ID查询子菜单
     * @param parentId 父菜单ID
     * @return
     */
    @GetMapping("/children")
    @ResponseBody
    @Operation(summary = "子菜单", description = "根据父菜单ID查询子菜单")
    public RespObj<?> children(@RequestParam Long parentId) {
        try {
            List<SysMenu> children = sysMenuService.getMenusByParentId(parentId);
            return new RespObj<>().success(children);
            
        } catch (Exception e) {
            return new RespObj<>().error("查询子菜单失败：" + e.getMessage());
        }
    }

    /**
     * 根据用户ID查询用户菜单
     * @param userId 用户ID
     * @return
     */
    @GetMapping("/user_menus")
    @ResponseBody
    @Operation(summary = "用户菜单", description = "根据用户ID查询用户可访问的菜单")
    public RespObj<?> userMenus(@RequestParam Long userId) {
        try {
            if (userId == null) {
                return new RespObj<>().error("用户ID不能为空");
            }
            
            List<SysMenu> menus = sysMenuService.getMenusByUserId(userId);
            return new RespObj<>().success(menus);
            
        } catch (Exception e) {
            return new RespObj<>().error("查询用户菜单失败：" + e.getMessage());
        }
    }

    /**
     * 根据角色ID查询角色菜单
     * @param roleId 角色ID
     * @return
     */
    @GetMapping("/role_menus")
    @ResponseBody
    @Operation(summary = "角色菜单", description = "根据角色ID查询角色可访问的菜单")
    public RespObj<?> roleMenus(@RequestParam Long roleId) {
        try {
            if (roleId == null) {
                return new RespObj<>().error("角色ID不能为空");
            }
            
            List<SysMenu> menus = sysMenuService.getMenusByRoleId(roleId);
            return new RespObj<>().success(menus);
            
        } catch (Exception e) {
            return new RespObj<>().error("查询角色菜单失败：" + e.getMessage());
        }
    }

    /**
     * 根据系统类型查询菜单
     * @param system 系统类型
     * @return
     */
    @GetMapping("/system_menus")
    @ResponseBody
    @Operation(summary = "系统菜单", description = "根据系统类型查询菜单")
    public RespObj<?> systemMenus(@RequestParam Integer system) {
        try {
            if (system == null) {
                return new RespObj<>().error("系统类型不能为空");
            }
            
            List<SysMenu> menus = sysMenuService.getMenusBySystem(system);
            return new RespObj<>().success(menus);
            
        } catch (Exception e) {
            return new RespObj<>().error("查询系统菜单失败：" + e.getMessage());
        }
    }

    /**
     * 检查菜单名称是否唯一
     * @param menuName 菜单名称
     * @param parentId 父菜单ID
     * @param menuId 菜单ID（编辑时传入，新增时不传）
     * @return
     */
    @GetMapping("/check_menu_name")
    @ResponseBody
    @Operation(summary = "检查菜单名称", description = "检查菜单名称是否唯一")
    public RespObj<?> checkMenuName(@RequestParam String menuName,
                                   @RequestParam(defaultValue = "0") Long parentId,
                                   @RequestParam(required = false) Long menuId) {
        try {
            if (!org.springframework.util.StringUtils.hasText(menuName)) {
                return new RespObj<>().error("菜单名称不能为空");
            }
            
            boolean exists = sysMenuService.checkMenuNameExists(menuName, parentId, menuId);
            return new RespObj<>().success(!exists);
            
        } catch (Exception e) {
            return new RespObj<>().error("检查菜单名称失败：" + e.getMessage());
        }
    }

    /**
     * 获取菜单选择列表
     * @return
     */
    @GetMapping("/select_list")
    @ResponseBody
    @Operation(summary = "菜单选择列表", description = "获取菜单选择列表，用于下拉框等")
    public RespObj<?> selectList() {
        try {
            List<SysMenu> menus = sysMenuService.getMenuSelectList();
            return new RespObj<>().success(menus);
            
        } catch (Exception e) {
            return new RespObj<>().error("获取菜单选择列表失败：" + e.getMessage());
        }
    }

    /**
     * 导出菜单数据
     * @param menuName 菜单名称
     * @param status 状态
     * @param menuType 菜单类型
     * @param system 系统类型
     * @return
     */
    @GetMapping("/export")
    @ResponseBody
    @LogAop(remark = "导出菜单数据")
    @Operation(summary = "导出菜单", description = "导出菜单数据")
    public RespObj<?> export(@RequestParam(required = false) String menuName,
                            @RequestParam(required = false) String status,
                            @RequestParam(required = false) String menuType,
                            @RequestParam(required = false) Integer system) {
        try {
            // 构建查询条件
            SysMenu queryMenu = new SysMenu();
            if (org.springframework.util.StringUtils.hasText(menuName)) {
                queryMenu.setMenuName(menuName);
            }
            if (org.springframework.util.StringUtils.hasText(status)) {
                queryMenu.setStatus(status);
            }
            if (org.springframework.util.StringUtils.hasText(menuType)) {
                queryMenu.setMenuType(menuType);
            }
            if (system != null) {
                queryMenu.setSystem(system);
            }
            
            List<SysMenu> menus = sysMenuService.exportMenus(queryMenu);
            return new RespObj<>().success(menus);
            
        } catch (Exception e) {
            return new RespObj<>().error("导出菜单数据失败：" + e.getMessage());
        }
    }
}
